package com.atguigu.gmall.item.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.item.service.ItemService;
import com.atguigu.gmall.list.client.ListFeignClient;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.product.model.*;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

/**
 * @author: atguigu
 * @create: 2023-04-22 09:12
 */
@Service
@SuppressWarnings("all")
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ListFeignClient listFeignClient;

    @Autowired
    private Executor executor;

    /**
     * 查询商品信息,汇总详情页面需要数据
     * 1.根据SkuID查询商品SKU基本信息包含图片列表-返回sku商品对象
     * 2.根据三级分类ID查询所属分类信息
     * 3.根据SkuID查询价格
     * 4.根据spuId查询商品海报列表
     * 5.根据skuId查询平台属性列表
     * 6.根据spuID+SkuId查询销售属性 选中当前商品销售属性
     * 7.根据spuID查询销售属性跟sku对照关系-选择销售属性组合,切换SKU
     *
     * @param skuId
     * @return
     */
    @Override
    public Map<String, Object> getItemInfo(Long skuId) {

        //0.判断用户访问商品不存在 则说明是非法访问,直接返回  反之执行远程调用 todo 交付测试前注释放开
        //RBloomFilter<Long> bloomFilter = redissonClient.getBloomFilter(RedisConst.SKU_BLOOM_FILTER);
        //boolean contains = bloomFilter.contains(skuId);
        //if (!contains) {
        //    throw new RuntimeException("访问数据不存在!");
        //}

        Map<String, Object> mapResult = new HashMap<>();

        //1. 根据SkuID查询商品SKU基本信息包含图片列表 - 返回sku商品对象  -- 产生异步任务对象-后续其他任务需要使用返回结果
        CompletableFuture<SkuInfo> skuInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            if (skuInfo != null) {
                mapResult.put("skuInfo", skuInfo);
            }
            return skuInfo;
        }, executor);

        //2. 根据三级分类ID查询所属分类信息     -- 当前异步任务对象依赖于其他线程,获取上一个线程返回结果
        CompletableFuture<Void> categorCompletableFuture = skuInfoCompletableFuture.thenAccept(skuInfo -> {
            BaseCategoryView categoryView = productFeignClient.getCategoryView(skuInfo.getCategory3Id());
            if (categoryView != null) {
                mapResult.put("categoryView", categoryView);
            }
        });

        //3. 根据SkuID查询价格
        CompletableFuture<Void> priceCompletableFuture = CompletableFuture.runAsync(() -> {
            BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
            if (skuPrice != null) {
                mapResult.put("price", skuPrice);
            }
        }, executor);

        //4. 根据spuId查询商品海报列表
        CompletableFuture<Void> spuPosterListCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            List<SpuPoster> spuPosterList = productFeignClient.getSpuPosterBySpuId(skuInfo.getSpuId());
            if (!CollectionUtils.isEmpty(spuPosterList)) {
                mapResult.put("spuPosterList", spuPosterList);
            }
        }, executor);

        //5. 根据skuId查询平台属性列表
        CompletableFuture<Void> skuAttrListCompletableFuture = CompletableFuture.runAsync(() -> {
            List<BaseAttrInfo> attrInfoList = productFeignClient.getAttrList(skuId);
            if (!CollectionUtils.isEmpty(attrInfoList)) {
                mapResult.put("skuAttrList", attrInfoList);
            }
        }, executor);


        //6. 根据spuID + SkuId查询销售属性 选中当前商品销售属性
        CompletableFuture<Void> spuSaleAttrListCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            List<SpuSaleAttr> spuSaleAttrList = productFeignClient.getSpuSaleAttrListCheckBySku(skuId, skuInfo.getSpuId());
            if (!CollectionUtils.isEmpty(spuSaleAttrList)) {
                mapResult.put("spuSaleAttrList", spuSaleAttrList);
            }
        }, executor);

        //7. 根据spuID查询销售属性跟sku对照关系-选择销售属性组合,切换SKU  TODO 前端解析是JSON字符串
        CompletableFuture<Void> valuesSkuJsonCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            Map skuValueIdsMap = productFeignClient.getSkuValueIdsMap(skuInfo.getSpuId());
            if (!CollectionUtils.isEmpty(skuValueIdsMap)) {
                mapResult.put("valuesSkuJson", JSON.toJSONString(skuValueIdsMap));
            }
        }, executor);

        //8.TODO 远程调用搜索微服务更新商品热度
        CompletableFuture<Void> goodsScoreCompletableFuture = CompletableFuture.runAsync(() -> {
            listFeignClient.incrHotScore(skuId);
        }, executor);

        //x.等待所有异步任务并行执行完毕,主线程继续执行响应结果
        CompletableFuture.allOf(
                skuInfoCompletableFuture,
                categorCompletableFuture,
                priceCompletableFuture,
                spuPosterListCompletableFuture,
                skuAttrListCompletableFuture,
                spuSaleAttrListCompletableFuture,
                valuesSkuJsonCompletableFuture,
                goodsScoreCompletableFuture
        ).join();
        return mapResult;
    }
}
